package com.sicong.common.security.filter;

import com.sicong.common.security.utils.TokenUtil;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 权限认证过滤器
 *
 * @author chenww
 * @date 2020-11-24
 */
@Order(-100)
public class TokenAuthenticationFilter extends OncePerRequestFilter {

    private final TokenUtil tokenUtil;

    private final CacheManager cacheManager;

    public TokenAuthenticationFilter(TokenUtil tokenUtil, CacheManager cacheManager) {
        this.tokenUtil = tokenUtil;
        this.cacheManager = cacheManager;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String token = request.getHeader("token");
        if (!StringUtils.isEmpty(token)) {
            String username = tokenUtil.getUsernameFromToken(token);
            Cache cache = cacheManager.getCache("user_authority");
            List<String> permissions = (List<String>) cache.get(username).get();
            Collection<GrantedAuthority> authorities = new ArrayList<>();
            if (permissions != null) {
                for (String permission : permissions) {
                    authorities.add(new SimpleGrantedAuthority(permission));
                }
            }
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken
                    = new UsernamePasswordAuthenticationToken(username, token, authorities);
            SecurityContext context = SecurityContextHolder.getContext();
            context.setAuthentication(usernamePasswordAuthenticationToken);
        }
        System.out.println(SecurityContextHolder.getContext().getAuthentication());
        // 如果是内部访问请求，则赋予空身份和权限，以让请求通过不被拦截
        if ("Inner".equals(request.getHeader("Inner"))) {
            SecurityContextHolder.getContext().setAuthentication(
                    new UsernamePasswordAuthenticationToken(null,null,null));
        }
        chain.doFilter(request, response);
    }

}
